package com.lmaos.allcontrol.beancontrol.paramInject_;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import com.lmaos.allcontrol.beancontrol.class_.ClassUtils;
import com.lmaos.allcontrol.beancontrol.entity_.LMClassParam;
import com.lmaos.allcontrol.beancontrol.utils_.InjectorParams;
/** 注解注入方式
 * 
 * @author lmaos
 *
 * <p>作者：张星宇</p>
 * <p>时间：2017年12月17日 下午6:08:41</p>
 * <p>说明:		</p>
 *
 */
public abstract class InjectorParamsAnnotation implements InjectorParams{
	protected final static Object[] em = new Object[0];
	
	@Override
	public Object[] getParamsValue(AccessibleObject accessibleObject, Class[] types, LMClassParam params) {
		if(types == null||types.length==0){
			return em;
		}
		Annotation rootAnns[] =  accessibleObject.getAnnotations();
		Map<Class, Annotation> methodAnnsCache = new HashMap<Class, Annotation>();
		for (Annotation annotation : rootAnns) {
			if(annotation!=null){
				methodAnnsCache.put(annotation.annotationType(), annotation);
			}
		}
		// 获得参数注解
		Annotation[][] paramsAnnotation = getParamsAnnotation(accessibleObject, types, params);
		Object[] paramValues = new Object[types.length]; // 参数对象
		for (int i = 0; i < types.length; i++) {
			Annotation[] paramsAnns = paramsAnnotation[i];
			Map<Class, Annotation> paramsAnnCache = new HashMap<Class, Annotation>();
			if(paramsAnns!=null&&paramsAnns.length > 0){
				for (Annotation annotation : paramsAnns) {
					if(annotation!=null){
						paramsAnnCache.put(annotation.annotationType(), annotation);
					}
				}
			}
			Class type = types[i];
			paramValues[i] = getParamValue(methodAnnsCache,paramsAnnCache,accessibleObject,i, type, params);
			// 当参数为null 时的解决方案
			if(paramValues[i] == null){
				paramValues[i] = ClassUtils.getValueAndNullSetDefVal(params.get(type), type);
			}
		}
		
		return paramValues;
	}
	
	protected Annotation[][] getParamsAnnotation(AccessibleObject accessibleObject, Class[] types, LMClassParam params){
		if(accessibleObject instanceof Method){
			return ((Method)accessibleObject).getParameterAnnotations();
		}
		if(accessibleObject instanceof Constructor){
			return ((Constructor)accessibleObject).getParameterAnnotations();
		}
		return null;
	}
	/**
	 * 说明：得到当前类型的参数对象		<br>
	 * 时间：2017年12月17日 下午6:07:13
	 *
	 * @param paramsAnnCache	key = 注解当类型,val = 注解对象
	 * @param type
	 * @param params
	 * @return
	 */
	protected abstract Object getParamValue(Map<Class, Annotation> methodAnns,Map<Class, Annotation> paramsAnnCache,AccessibleObject accessibleObject,int index,Class type,LMClassParam params);
	
}
